/**
 * @author haina.z@163.com
 * @brief String handling.
 * @version V1.0
 */

/** Includes -----------------------------------------------------------------*/
#include "xstring.h"

/** Macros and constants -----------------------------------------------------*/

/** Type definitions ---------------------------------------------------------*/

/** Private variable definitions (static) ------------------------------------*/

/** Static function declarations (prototypes) --------------------------------*/

/** Public variable definitions ----------------------------------------------*/

/** Pre-compile check --------------------------------------------------------*/

/** Code ---------------------------------------------------------------------*/

/**
 * @brief Search Key, return first matched
 * @author Zhu Zhengxing
 * @date 2021.10.17
 */
int16_t xString_SearchKey(const char *sSource, const char *sKey)
{
    uint16_t i, j;

    if (*sKey == '\0')
    {
        return XSTRING_FAIL;
    }

    // Start address for comparison
    for (i = 0; ((i < 0x7FFF) && (sSource[i] != '\0')); i++)
    {
        for (j = 0; ((i + j) < 0x7FFF); j++)
        {
            // Match with sKey
            if (sKey[j] == '\0')
            {
                return i;
            }
            // Different, including sSource[i + j] == '\0'
            else if (sSource[i + j] != sKey[j])
            {
                break;
            }
        }
    }

    return XSTRING_FAIL;
}

/**
 * @brief String to hex value
 * @author Zhu Zhengxing
 * @date 2021.10.17
 */
int16_t xString_StringToHex(const char *sString, uint8_t *pBuf, uint16_t u16BufSize)
{
    uint16_t u16Index;
    uint8_t u8Tmp, u8Value;

    for (u16Index = 0; ((u16Index / 2 < u16BufSize) && (sString[u16Index] != '\0')); u16Index++)
    {
        if (u16Index & 0x1) // The lower 4 bits of a byte
        {
            u8Tmp = CHAR_TO_NIBBLE(sString[u16Index]);
            if (u8Tmp == ' ')
            {
                return XSTRING_FAIL;
            }
            u8Value += u8Tmp;
            *pBuf++ = u8Value; // Assign and point to the next address
        }
        else // The upper 4 bits of a byte
        {
            u8Tmp = CHAR_TO_NIBBLE(sString[u16Index]);
            if (u8Tmp == ' ')
            {
                return XSTRING_FAIL;
            }
            u8Value = u8Tmp * 16;
        }
    }

    // Non even number of strings
    if ((u16Index & 0x1) || (sString[u16Index] != '\0'))
    {
        return XSTRING_FAIL;
    }

    return (int16_t)(u16Index / 2);
}

/**
 * @brief Hex string to value
 * @author Zhu Zhengxing
 * @date 2021.11.17
 */
bool xString_HexStringToValue(const char *sString, uint8_t *pBuf, uint8_t u8Number)
{
    uint16_t u16Index;
    uint8_t u8Tmp, u8Value;

    for (u16Index = 0; u16Index / 2 < u8Number; u16Index++)
    {
        if (u16Index & 0x1) // The lower 4 bits of a byte
        {
            u8Tmp = CHAR_TO_NIBBLE(sString[u16Index]);
            if (u8Tmp == ' ')
            {
                return false;
            }
            u8Value += u8Tmp;
            *pBuf++ = u8Value; // Assign and point to the next address
        }
        else // The upper 4 bits of a byte
        {
            u8Tmp = CHAR_TO_NIBBLE(sString[u16Index]);
            if (u8Tmp == ' ')
            {
                return false;
            }
            u8Value = u8Tmp * 16;
        }
    }

    return true;
}

/******************************** End of file *********************************/
